package org.ala.shopping_test.shopping_center.service;

import org.ala.shopping_test.shopping_center.repository.category.entity.ShoppingCategoryDO;
import org.ala.shopping_test.shopping_center.repository.order.dao.ShoppingOrderMapper;
import org.ala.shopping_test.shopping_center.repository.order.entity.ShoppingOrderDO;
import org.ala.shopping_test.shopping_center.repository.order_buyer.dao.ShoppingOrderBuyerMapper;
import org.ala.shopping_test.shopping_center.repository.order_buyer.entity.ShoppingOrderBuyerDO;
import org.ala.shopping_test.shopping_center.repository.order_seller.dao.ShoppingOrderSellerMapper;
import org.ala.shopping_test.shopping_center.repository.order_seller.entity.ShoppingOrderSellerDO;
import org.ala.shopping_test.user_center.repository.user.entity.UserBuyerDO;
import org.ala.shopping_test.user_center.repository.user.entity.UserSellerDO;
import org.ala.shopping_test.user_center.service.UserService;
import org.ala.tiktools.logs.LoggerFactory;
import org.ala.tiktools.sharddb.tools.SnowIdGenerator;
import org.ala.tiktools.tools.TimestampTools;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.*;

/**
 * 造数据
 *
 * @author ala
 * @date 2025-03-17 12:48
 */
@Component
public class ShoppingOrderCreator {


    static Logger log = LoggerFactory.getLogger("shopping", "creator");


    @Autowired
    protected ShoppingCategoryService shoppingCategoryService;
    @Autowired
    protected UserService userService;

    @Autowired
    protected ShoppingOrderMapper shoppingOrderMapper;
    protected SnowIdGenerator orderIdGenerator = SnowIdGenerator.build(1);

    @Autowired
    protected ShoppingOrderBuyerMapper shoppingOrderBuyerMapper;
    protected SnowIdGenerator orderBuyerIdGenerator = SnowIdGenerator.build(1);
    @Autowired
    protected ShoppingOrderSellerMapper shoppingOrderSellerMapper;
    protected SnowIdGenerator orderSellerIdGenerator = SnowIdGenerator.build(1);

    protected Random random = new Random(1024);


    /**
     *  1天n条，造m天，每b条batch一次
     *  买家卖家随机
     */
    public void createOrder(int n, int m, int b, List<UserBuyerDO> buyers, List<UserSellerDO> sellers) {
        RandomT<UserBuyerDO> rb = new RandomT<>(buyers);
        RandomT<UserSellerDO> rs = new RandomT<>(sellers);

        List<ShoppingOrderDO> orders = new ArrayList<>();
        List<ShoppingOrderBuyerDO> buyerOrders = new ArrayList<>();
        List<ShoppingOrderSellerDO> sellerOrders = new ArrayList<>();

        UserBuyerDO buyer = null;
        UserSellerDO seller = null;

        double total = n * m, crt = 0d;
        double p = 0d;

        //  连着往前造m天
        for (int i = 0 ; i < m ; i++) {
            //  每天n条
            for (int j = 0 ; j < n ; j++) {
                createOrder(rb.random(), rs.random(), i, orders, buyerOrders, sellerOrders);
                //  每b条批量一次
                if ((orders.size()+1) % b == 0) {
                    crt += orders.size();
                    p = crt / total;
                    System.out.printf("任务进度:(%.4f) \n", p);

                    saveAndClear(orders, buyerOrders, sellerOrders);
                    orders = new ArrayList<>();
                    buyerOrders = new ArrayList<>();
                    sellerOrders = new ArrayList<>();
                }
            }
            if (!orders.isEmpty()) {
                crt += orders.size();
                p = crt / total;
                System.out.printf("任务进度:%.2f \n", p);

                saveAndClear(orders, buyerOrders, sellerOrders);
                orders = new ArrayList<>();
                buyerOrders = new ArrayList<>();
                sellerOrders = new ArrayList<>();
            }
            log.info(String.format("造完第(%d)天的数据", i));
        }

        return;
    }
    /**
     *  保存并且清空list
     */
    protected void saveAndClear(List<ShoppingOrderDO> orders,
                                List<ShoppingOrderBuyerDO> buyerOrders,
                                List<ShoppingOrderSellerDO> sellerOrders) {
    	//	批量插入订单
        shoppingOrderMapper.multipleInsert(orders);
        orders.clear();
        //	批量插入买家订单
        shoppingOrderBuyerMapper.multipleInsert(buyerOrders);
        buyerOrders.clear();
        //	批量插入卖家订单
        shoppingOrderSellerMapper.multipleInsert(sellerOrders);
        sellerOrders.clear();
    }
    /**
     *  随机产生一条订单
     */
    protected void createOrder(UserBuyerDO buyer, UserSellerDO seller, int day,
                               List<ShoppingOrderDO> orders,
                               List<ShoppingOrderBuyerDO> buyerOrders,
                               List<ShoppingOrderSellerDO> sellerOrders
                               ) {
        //  产生随机订单id
        SnowIdGenerator.Id orderId = orderIdGenerator.id(),
                buyerOrderId = orderBuyerIdGenerator.id(),
                sellerOrderId = orderSellerIdGenerator.id();
        long now = orderId.getTimestamp() - day * TimestampTools.DAY_MS;

        //  产生随机订单金额 (0, 100]，优惠金额，税，盈利金额
        double amount = random.nextDouble() * 100, discount = random.nextDouble() * (amount / 10), tax = random.nextDouble() * (amount / 5), profit = amount - discount - tax;

        ShoppingOrderDO order = ShoppingOrderDO.build()
                .id(orderId.getId()).orderType(0).status(0).abnormal(0)
                .buyerId(buyer.getId()).buyerOrderId(buyerOrderId.getId()).byuerName(buyer.getBuyerName())
                .sellerId(seller.getId()).sellerOrderId(sellerOrderId.getId()).sellerName(seller.getSellerName())
                .orderAmount(BigDecimal.valueOf(amount)).orderProfit(BigDecimal.valueOf(profit)).orderTax(BigDecimal.valueOf(tax)).orderDiscountAmount(BigDecimal.valueOf(discount))
                .createTime(now).modifyTime(now);
        orders.add(order);

        ShoppingOrderBuyerDO buyerOrder = ShoppingOrderBuyerDO.build()
                .id(buyerOrderId.getId()).orderId(orderId.getId()).status(0).abnormal(0)
                .buyerId(order.getBuyerId()).buyerName(order.getByuerName())
                .sellerId(order.getSellerId()).sellerOrderId(order.getSellerOrderId()).sellerName(order.getSellerName())
                .orderAmount(order.getOrderAmount()).orderProfit(order.getOrderProfit()).orderTax(order.getOrderTax()).orderDiscountAmount(order.getOrderDiscountAmount())
                .createTime(order.getCreateTime()).modifyTime(order.getModifyTime());
        buyerOrders.add(buyerOrder);

        ShoppingOrderSellerDO sellerOrder = ShoppingOrderSellerDO.build()
                .id(buyerOrderId.getId()).orderId(orderId.getId()).status(0).abnormal(0)
                .sellerId(order.getSellerId()).sellerName(order.getSellerName())
                .buyerId(order.getBuyerId()).buyerOrderId(order.getBuyerOrderId()).buyerName(order.getByuerName())
                .orderAmount(order.getOrderAmount()).orderProfit(order.getOrderProfit()).orderTax(order.getOrderTax()).orderDiscountAmount(order.getOrderDiscountAmount())
                .createTime(order.getCreateTime()).modifyTime(order.getModifyTime());
        sellerOrders.add(sellerOrder);
    }


    /**
     *  随机选择器
     */
    static class RandomT<T> {
        List<T> ts;
        int N = 0;
        Random random;
        public RandomT(List<T> ts) {
            this.ts = ts;
            this.N = ts.size();
            this.random = new Random(1024);
        }
        public T random(int a, int b) {
            b = Math.min(b, N);
            int i = (int)(random.nextDouble() * (b - a) + a);
            return ts.get(i);
        }
        public T random() {
            int i = (int)(random.nextDouble() * (N-1));
            return ts.get(i);
        }
    }


}
